package order

import (
	"context"
	baseModel "service/model/crm_base"
	model "service/model/crm_order"
	hmodel "service/model/hr"
	hrModel "service/model/hr_cache"
	kbModel "service/model/kb_pro"
	"service/model/mod"
	proModel "service/model/project_cache"
	"strconv"
	"time"

	gpc "gitee.com/cloudapex/protos/comm/pb"
	gpb "gitee.com/cloudapex/protos/crm_order/pb"
	hpb "gitee.com/cloudapex/protos/hr/pb"
	hrGpb "gitee.com/cloudapex/protos/hr_cache/pb"
	kbGpb "gitee.com/cloudapex/protos/pro_know/pb"
	proGpb "gitee.com/cloudapex/protos/project_cache/pb"
	"gitee.com/cloudapex/ulern/util"
)

//获取班型信息
func GetClassInfo(ctx context.Context, id int64) (*kbGpb.Class, error) {

	var proclas kbGpb.ProClassReq
	var class kbGpb.Class
	var pro kbGpb.Project
	class.Id = id
	proclas.Class = &class
	proclas.Pro = &pro
	prolist := kbGpb.ProListReq{ProClassReq: &proclas, Page: 1, Count: 1}
	rep, err := kbModel.ProClass.GetProClassList(ctx, &prolist)
	if err != nil {
		util.Debug("%s", err)
		return &kbGpb.Class{}, err
	}
	classInfo := rep.ProList[0].Class
	return classInfo, nil

}

func AddClassStudentCount(ctx context.Context, classId int64, phone string) {

	req := &gpb.UserClassListReq{
		UserClass: &gpb.UserClass{
			CId:   classId,
			Phone: phone,
		},
	}
	model.UserClass.GetUserClassList(ctx, req)
}

//构造高 、低班型协议结构，方便后边插入数据库

func CreateAgreeSign(ctx context.Context, classInfo *kbGpb.Class, i int, list []*gpb.CrmOrderInfoRes) (OrAgreeType, OrAgreeType) {

	var senior, low OrAgreeType
	util.Debug("%s", classInfo)
	if re, tids := IsNeedSign(classInfo, ctx); re {
		if classInfo.UpgRade == 1 {
			senior.Type = 2
			senior = AgreeUpdate(senior, tids, i, list)
		} else {
			low.Type = 1
			low = AgreeUpdate(low, tids, i, list)
		}
	}
	return senior, low
}

func AgreeUpdate(agree OrAgreeType, tids []int, i int, list []*gpb.CrmOrderInfoRes) OrAgreeType {

	agree.TerminalIds = AppendSlice(agree.TerminalIds, tids)
	agree.TerminalIdStr = IntToString(agree.TerminalIds)

	pid_str := strconv.Itoa(int(list[i].ProjectId))
	if i == 0 || agree.Pidstr == "" {
		agree.Pidstr += pid_str
	} else {
		agree.Pidstr += "," + pid_str
	}

	if !isInSlice(list[i].ProjectId, agree.NewSlice) {
		if i == 0 || agree.Pname == "" {
			agree.Pname += list[i].ProjectName
		} else {
			agree.Pname += "," + list[i].ProjectName
		}
		agree.NewSlice = append(agree.NewSlice, list[i].ProjectId)
	}

	cid_str := strconv.Itoa(int(list[i].ClassId))
	if i == 0 || agree.Cname == "" {
		agree.Cidstr += cid_str
		agree.Cname += list[i].ClassName
	} else {
		agree.Cidstr += "," + cid_str
		agree.Cname += "," + list[i].ClassName
	}
	return agree
}

func AddAutoAssignLog(ctx context.Context, companyId int64, orderId int64, userId int64, name string) error {

	autoAssignReq := &hrGpb.LoginCacheReq{
		Id: mod.AutoAssignId,
	}
	autoAssignInfo, err := hrModel.UserCacheServer.GetAllLoginCache(ctx, autoAssignReq)
	util.Debug("%s", autoAssignInfo)
	if err != nil {
		util.Debug("获取自动分配人信息失败：%s", err)
		return err
	}
	// 分配记录
	_, err = model.Order.CrmOrderLogCreate(ctx, &gpb.CrmOrderLogReq{
		CommpId:   companyId,
		OrderId:   orderId,
		UserId:    userId,
		UserName:  name,
		RoleId:    autoAssignInfo.UserInfo.RoleId,
		AdminId:   mod.AutoAssignId,
		AdminName: autoAssignInfo.UserInfo.Name,
		Status:    int64(mod.EOrderL_Assign),
	})
	return err

}

//分配班主任，更新订单状态
func AssignTeacherAndUpdateOrder(ctx context.Context, res *gpb.CrmOrderCreateRes, updateReq *gpb.CrmOrderStatusReq, isSenior int64, userinfo *hrGpb.UserLoginRes) error {

	updateReq.Status = 2
	if res.RoleId == 1 {

		util.Debug("招生进入")
		//班主任的话，直接将学员分配给自己
		stuReq := &gpb.StudentOrderGetReq{
			Phone: res.Phone,
		}
		stuRes, err := model.StudentOrder.StudentOrderGet(ctx, stuReq)
		if err != nil {
			util.Debug("获取班主任学员库信息失败：%s", err)
			return err
		}
		util.Debug("班主任学员库信息：%s", stuRes)

		if stuRes.CustomerId != 0 {

			changeOrder := &gpb.StudentOrderStatusReq{
				Phone:  res.Phone,
				Amount: res.TotalPrice + stuRes.Amount,
			}

			util.Debug("招生下单金额统计：%s", res.TotalPrice+stuRes.Amount)
			util.Debug("ton%s", res.TotalPrice)
			util.Debug("ton%s", stuRes.Amount)

			if stuRes.Senior != 2 && isSenior == 2 && res.BillType != 3 {
				changeOrder.Senior = isSenior
			}

			_, err = model.StudentOrder.StudentOrderStatus(ctx, changeOrder)
			if err != nil {
				util.Debug("更新学员库成交金额失败：%s", err)
				return err
			}

			if res.BillType != 3 && res.OrderType == 1 && stuRes.UserId > 0 {

				updateReq.TeachId = int64(stuRes.UserId)
				err = AddAutoAssignLog(ctx, res.CommpId, res.OrderId, int64(stuRes.UserId), stuRes.UserName)
				if err != nil {
					util.Debug("添加分配记录失败：%s", err)
					return err
				}
				updateReq.Status = 3
			}
		} else {
			//创建没有班主任的学员库信息，方便统计成交金额

			proInfo, err := GetProjectInfo(ctx, res.CustomerId, res.CommpId)
			if err != nil {
				util.Debug("获取项目信息失败：%s", err)
				return err
			}
			createReq := &gpb.StudentCreateReq{
				CommpId:     res.CommpId,
				Phone:       res.Phone,
				CustomerId:  uint64(res.CustomerId),
				Amount:      res.TotalPrice,
				Senior:      isSenior,
				ProjectId:   proInfo.ProjectId,
				ProjectName: proInfo.ProjectName,
			}
			_, err = model.StudentOrder.StudentOrderCreate(ctx, createReq)
			if err != nil {
				util.Debug("创建班主任学员库信息失败：%s", err)
				return err
			}
		}

	} else if res.RoleId == 2 {

		util.Debug("班主任进入")
		//班主任的话，直接将学员分配给自己
		stuReq := &gpb.StudentOrderGetReq{
			Phone: res.Phone,
		}
		stuRes, err := model.StudentOrder.StudentOrderGet(ctx, stuReq)
		if err != nil {
			util.Debug("%s", err)
			return err
		}
		util.Debug("班主任学员库信息：%s", stuRes)

		//第一次学员库信息为空
		if stuRes.CustomerId == 0 {

			proInfo, err := GetProjectInfo(ctx, res.CustomerId, res.CommpId)
			if err != nil {
				util.Debug("获取项目信息失败：%s", err)
				return err
			}

			if res.BillType != 3 && res.OrderType == 1 {

				createReq := &gpb.StudentCreateReq{
					CommpId:     res.CommpId,
					Phone:       res.Phone,
					CustomerId:  uint64(res.CustomerId),
					Amount:      res.TotalPrice,
					UserId:      res.UserId,
					UserName:    userinfo.UserInfo.Name,
					Senior:      isSenior,
					ProjectId:   proInfo.ProjectId,
					ProjectName: proInfo.ProjectName,
				}

				if _, err := model.StudentOrder.StudentOrderCreate(ctx, createReq); err != nil {
					util.Debug("创建班主任学员库信息失败：%s", err)
					return err
				}

				if err = AddAutoAssignLog(ctx, res.CommpId, res.OrderId, res.UserId, userinfo.UserInfo.Name); err != nil {
					util.Debug("添加分配记录失败：%s", err)
					return err
				}

				if _, err = baseModel.Work.DelWorkPool(ctx, &gpc.BaseReq{Id: uint64(res.CustomerId)}); err != nil {
					util.Debug("删除工作池失败：%s", err)
					return err
				}
				updateReq.TeachId = res.UserId
				updateReq.Status = 3
			} else {

				createReq := &gpb.StudentCreateReq{
					CommpId:     res.CommpId,
					Phone:       res.Phone,
					CustomerId:  uint64(res.CustomerId),
					Amount:      res.TotalPrice,
					Senior:      isSenior,
					ProjectId:   proInfo.ProjectId,
					ProjectName: proInfo.ProjectName,
				}

				if _, err = model.StudentOrder.StudentOrderCreate(ctx, createReq); err != nil {
					util.Debug("创建班主任学员库信息失败：%s", err)
					return err
				}
			}

		} else {

			changeOrder := &gpb.StudentOrderStatusReq{
				Phone:  res.Phone,
				Amount: res.TotalPrice + stuRes.Amount,
				StuId:  stuRes.StudentId,
			}

			if stuRes.Senior != 2 && isSenior == 2 && res.BillType != 3 {
				changeOrder.Senior = isSenior
			}

			if stuRes.UserId == 0 && res.OrderType == 1 {
				changeOrder.DistrId = res.UserId
				changeOrder.DistrAt = time.Now().Unix()
				req := &hrGpb.LoginCacheReq{
					Id: res.UserId,
				}
				distrInfo, err := hrModel.UserCacheServer.GetAllLoginCache(ctx, req)
				util.Debug("%s", distrInfo)
				if err != nil {
					util.Debug("%s", err)
					return err
				}
				changeOrder.DistrName = distrInfo.UserInfo.Name
			}

			util.Debug("更新学员库信息为：%s", changeOrder)

			_, err = model.StudentOrder.StudentOrderStatus(ctx, changeOrder)
			if err != nil {
				util.Debug("更新学员库成交金额失败：%s", err)
				return err
			}
			if res.BillType != 3 && res.OrderType == 1 {

				var banId int64
				if changeOrder.DistrId > 0 {
					banId = changeOrder.DistrId
				} else {
					banId = int64(stuRes.UserId)
				}

				var name string
				if changeOrder.DistrId > 0 {
					name = changeOrder.DistrName
				} else {
					name = stuRes.UserName
				}

				updateReq.TeachId = banId
				err = AddAutoAssignLog(ctx, res.CommpId, res.OrderId, banId, name)
				if err != nil {
					util.Debug("添加分配记录失败：%s", err)
					return err
				}
				updateReq.Status = 3

				_, err = baseModel.Work.DelWorkPool(ctx, &gpc.BaseReq{Id: uint64(res.CustomerId)})
				if err != nil {
					util.Debug("删除工作池失败：%s", err)
					return err
				}

			}
		}
	}

	_, err := model.Order.CrmOrderUpdate(ctx, updateReq)
	if err != nil {
		util.Debug("更新订单状态失败：%s", err)
		return err
	}
	return nil
}

func GetProjectInfo(ctx context.Context, CustomerId int64, companyId int64) (*proGpb.CrmProjectInfoRes, error) {
	proIdstr := strconv.Itoa(int(CustomerId))
	proIdstr1 := proIdstr[0:3]
	util.Debug("项目id%s", proIdstr1)
	proId, _ := strconv.ParseInt(proIdstr1, 10, 64)
	proInfo, err := proModel.ProjectCache.CrmProjectCacheGet(ctx, &proGpb.CrmProjectInfoReq{CommpId: companyId, Id: proId})
	util.Debug("获取项目信息：%s", proInfo)
	if err != nil {
		util.Debug("获取项目信息失败：%s", err)
		return &proGpb.CrmProjectInfoRes{}, err
	}
	return proInfo, nil
}

func GetShowIds(ctx context.Context, userId int64) ([]uint64, error) {
	req := &hrGpb.LoginCacheReq{
		Id: userId,
	}
	distrInfo, err := hrModel.UserCacheServer.GetAllLoginCache(ctx, req)
	if err != nil {
		return []uint64{}, err
	}

	rsps, err := hmodel.StaffServer.GetStaffShows(ctx, &hpb.StaffShowsReq{Hids: []int64{distrInfo.UserInfo.HId}})
	if err != nil {
		return []uint64{}, err
	}

	util.Debug("获取用户的可见区间范围：", rsps)
	util.Debug("用户信息：", distrInfo)

	if len(rsps.StaffShows) == 0 {
		return []uint64{}, nil
	}
	shows := []uint64{}
	for _, it := range rsps.StaffShows {
		shows = append(shows, it.ShowUIntId)
	}

	shows = mod.SectionDecovered(shows)
	return shows, nil

}

func IsGet(userShowIds []uint64, showId uint64) bool {

	var bl bool = false //数据是否在用户的可见区间
	dMax := mod.SectionNew(showId)

	util.Debug("数据的可见区间范围:%s", dMax)

	for _, v := range userShowIds {
		nMax := mod.SectionNew(v)

		util.Debug("用户的可见区间范围id%s", nMax)

		if nMax > showId && showId >= v {
			bl = true
		}
		if dMax > v && v >= showId {
			bl = true
		}
	}
	return bl
}

func IsGetFrame(userShowIds []uint64, showId uint64) bool {
	var bl bool = false //数据是否在用户的可见区间
	for _, v := range userShowIds {
		nMax := mod.SectionNew(v)
		util.Debug("用户的可见区间范围id%s", nMax)
		if nMax > showId && showId >= v {
			bl = true
		}
	}
	return bl
}
